package com.yht.redbook.user.relation.biz.exception;

import com.yht.framework.common.exception.BizException;
import com.yht.framework.common.response.Response;
import com.yht.redbook.user.relation.biz.enums.ResponseCodeEnum;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Optional;

/**
 * 全局异常处理
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 捕获自定义异常
     *
     * @param httpServletRequest
     * @param exception
     * @return
     */
    @ExceptionHandler({BizException.class})
    @ResponseBody
    public Response<Object> handleBizException(HttpServletRequest httpServletRequest, BizException exception) {
        log.warn("{} request fail, errorCode: {}, errorMessage: {}", httpServletRequest.getRequestURI(), exception.getErrorCode(), exception.getErrorMessage());
        return Response.fail(exception);
    }

    /**
     * 捕获方法参数校验异常
     *
     * @param request
     * @param exception
     * @return
     */
    @ExceptionHandler({MethodArgumentNotValidException.class})
    @ResponseBody
    public Response<Object> handleMethodArgumentNotValidException(HttpServletRequest request, MethodArgumentNotValidException exception) {
        //参数异常错误码
        String errorCode = ResponseCodeEnum.PARAM_NOT_VALID.getErrorCode();

        //获取 BindingResult
        BindingResult bindingResult = exception.getBindingResult();

        StringBuilder builder = new StringBuilder();

        //获取校验不通过的字段，并且组合错误信息，格式为： email 邮箱格式不正确，当前值： '1213123@qq.com';
        Optional.ofNullable(bindingResult.getFieldErrors()).ifPresent(errors -> {
            errors.forEach(error -> builder.append(error.getField()).append(" ").append(error.getDefaultMessage()).append("，当前值：'").append(error.getRejectedValue()).append("'; "));
        });

        // 错误信息
        String errorMessage = builder.toString();

        log.warn("{}, request error, errorCode: {}, errorMessage: {}", request.getRequestURI(), errorCode, errorMessage);

        return Response.fail(errorCode, errorMessage);
    }

    /**
     * 参数校验异常
     *
     * @param request
     * @param illegalArgumentException
     * @return
     */
    @ExceptionHandler({IllegalArgumentException.class})
    @ResponseBody
    public Response<Object> handleIllegalArgumentException(HttpServletRequest request, IllegalArgumentException illegalArgumentException) {
        // 参数异常错误码
        String errorCode = ResponseCodeEnum.PARAM_NOT_VALID.getErrorCode();

        // 异常信息
        String errorMessage = illegalArgumentException.getMessage();

        log.warn("{} request error, errorCode: {}, errorMessage: {}", request.getRequestURI(), errorCode, errorMessage);

        return Response.fail(errorCode, errorMessage);
    }

    /**
     * 其他异常
     *
     * @param request
     * @param exception
     * @return
     */
    @ExceptionHandler({Exception.class})
    @ResponseBody
    public Response<Object> handleOtherException(HttpServletRequest request, Exception exception) {
        log.error("{} request error, ", request.getRequestURI(), exception);
        return Response.fail(ResponseCodeEnum.SYSTEM_ERROR);

    }
}
